#include <iostream>
#include <tuple>
#include "avl_tree.h"

using namespace std;

AVLTree::AVLTree()
{
    this->root = nullptr;
    this->size = 0;
    this->depth = 0;
}

void AVLTree::Insert(int val)
{
    this->root = this->insertNode(this->root, val);
    this->size++;
    this->depth = this->root->height;
}

void AVLTree::Delete(int val)
{
    this->root = this->deleteNode(this->root, val);
    this->size--;
    this->depth = this->root->height;
}

tuple<bool, TreeNode<int> *> AVLTree::Search(int val)
{
    TreeNode<int> *node = this->searchNode(this->root, val);
    return make_tuple(node != nullptr, node);
}

int AVLTree::Size() const
{
    return this->size;
}

int AVLTree::Depth() const
{
    return this->depth;
}

void inOrderTraversal(TreeNode<int> *root)
{
    if (root != nullptr)
    {
        inOrderTraversal(root->left);
        cout << root->val << " ";
        inOrderTraversal(root->right);
    }
}

void AVLTree::InOrderTraversal() const
{
    inOrderTraversal(this->root);
    cout << endl;
}

int main()
{
    AVLTree *tree = new AVLTree();
    tree->Insert(10);
    tree->Insert(20);
    tree->Insert(30);
    tree->Insert(40);
    tree->Insert(50);
    tree->Insert(25);
    tree->InOrderTraversal();
    tree->Delete(30);
    tree->InOrderTraversal();
    return 0;
}
